﻿#include"stdafx.h"
#ifdef LK_COLLECTION_MESSAGEPACK_
#ifdef LK_RANDOM_
namespace LK
{
	namespace Collection {
		MessagePack::MessagePack(u64 num, PByteArray  dat):Number(num),data(dat) {}

		/**
		@brief 将指定的数据打包进缓存块*/
		void DefaultMessageBuffer::PackToBuffer(void* p, u32 len,PTime const& timeout){
			if (!p||len > maxLength)Throw<PInvalidArgumentException>();
			s32 mlen = len&(~7);
			u64 alen = ((~(u64)len) << 32) | len;
			u64 rd = Random::GetDefaultRef()->Rand();
			index_t i;
			if (len & 7) { for ( i = 0; i < (index_t)(len & 7); ++i)((u8*)&rd)[i]=((u8*)p)[mlen + i]; }
			bool threadSafe = buffer.GetEnableThreadSafe();
			u64 msk = alen;
			for (i = 0; i < (mlen>>3); i++)msk ^= (((u64*)p)[i] << ((i + 2) & 63)) | ((((i + 2)&63)==0)?0:((((u64*)p)[i] >> (64-((i + 2) & 63)))));
			msk ^= (rd<< ((i + 2) & 63)) | ((((i + 2) & 63) == 0) ? 0 : ((rd >> (64 - ((i + 2) & 63)))));
			if (threadSafe)while(buffer.LockOperator(buffer.StateWriting)==0)Sleep(buffer.sleepTime);
			msk ^= ((inNumber<<1)|(inNumber>>63));
			if (buffer.Write(&alen, 8, timeout)!=8)Throw<PException>(L"缓存写入超时");
			if (buffer.Write(&msk, 8, timeout) != 8)Throw<PException>(L"缓存写入超时");
			if (buffer.Write(&inNumber, 8, timeout) != 8)Throw<PException>(L"缓存写入超时");
			if (buffer.Write(p, mlen, timeout) != mlen)Throw<PException>(L"缓存写入超时");
			if (buffer.Write(&rd, 8, timeout) != 8)Throw<PException>(L"缓存写入超时");
			inNumber++;
			if (threadSafe)while (buffer.UnlockOperator(buffer.StateWriting) == 0)Sleep(buffer.sleepTime);
		}
		/**
		@brief 返回一个存储Message的对象*/
		PMessagePack DefaultMessageBuffer::ReadMessage(PTime const& timeout) {
			//读取8字节
			u32 len[2];
			u64 msk=0;
			u64 num;
			bool threadSafe = buffer.GetEnableThreadSafe();
			if (threadSafe)while (buffer.LockOperator(buffer.StateReading) == 0)Sleep(buffer.sleepTime);
			if(buffer.Read(len, 8, timeout)!=8)Throw<PException>(L"缓存读取数据超时");
			index_t i= len[0];
			if ((u32)i != ~len[1] || (u32)i>maxLength)Throw<PIndexOutOfRangeException>();
			if(buffer.Read(&msk, 8, timeout) != 8)Throw<PException>(L"缓存读取数据超时");
			if(buffer.Read(&num, 8, timeout) != 8)Throw<PException>(L"缓存读取数据超时");
			msk^= ((num << 1) | (num >> 63));
			msk^= *(u64*)len;
			s32 mlen = (u32)i & (~7);
			PMessagePack pak = new MessagePack(num, new DefaultArray<u8>(i));
			if(buffer.Read(pak->data, i, timeout)!=i)Throw<PException>(L"缓存读取数据超时");
			if (i & 7) {
				i = (8 - (len[0] & 7));
				if(buffer.Read(&num, i, timeout) != i)Throw<PException>(L"缓存读取数据超时");
				num <<= 8*(len[0] & 7);
			}
			else {
				 if(buffer.Read(&num, 8, timeout) != 8)Throw<PException>(L"缓存读取数据超时");
			}
			u8* p = pak->data;
			if (len[0] & 7) { for (i = 0; i < (index_t)(len[0] & 7); ++i)((u8*)&num)[i] = ((u8*)p)[mlen + i]; }
			for (i = 0; i < (mlen>>3);++i)msk ^= (((u64*)p)[i] << ((i + 2) & 63)) | ((((i + 2) & 63) == 0) ? 0 : ((((u64*)p)[i] >> (64 - ((i + 2) & 63)))));
			msk ^=(num << ((i + 2) & 63)) | ((((i + 2) & 63) == 0) ? 0 : ((num >> (64 - ((i + 2) & 63)))));
			if (msk != 0)Throw<PException>(L"消息传输异常。");
			outNumber++;
			if (threadSafe)while (buffer.UnlockOperator(buffer.StateReading) == 0)Sleep(buffer.sleepTime);
			return pak;
		}
		/**
		@brief 使用一个序号和最大长度进行初始化*/
		DefaultMessageBuffer::DefaultMessageBuffer(u64 num, u32 maxlen):inNumber(num),outNumber(num),maxLength(maxlen) {}

		u32 DefaultMessageBuffer::DefaultMaxLength = 1024 * 1024 * 8;

	}
}
#endif
#endif